"""
日程管理相关的 API 路由
"""

from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth import get_current_active_family_member
from src.crud.schedule_crud import (
    add_schedule_participants,
    confirm_schedule_participation,
    create_schedule,
    delete_schedule,
    get_schedule_by_id,
    get_schedule_participants,
    get_schedule_stats,
    get_schedules,
    get_schedules_by_date_range,
    get_upcoming_schedules,
    update_schedule,
)
from src.database import get_db
from src.models.family_model import FamilyMember
from src.models.schedule_model import ScheduleParticipant
from src.schemas.schedule_schema import (
    ScheduleCreate,
    ScheduleDetailResponse,
    ScheduleList,
    ScheduleParticipantResponse,
    ScheduleResponse,
    ScheduleSearch,
    ScheduleStats,
    ScheduleUpdate,
)

router = APIRouter(prefix="/schedules", tags=["schedules"])


@router.post(
    "",
    response_model=ScheduleResponse,
    status_code=status.HTTP_201_CREATED,
    summary="创建日程",
)
async def create_schedule_endpoint(
    schedule: ScheduleCreate,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """创建日程"""
    try:
        db_schedule = await create_schedule(
            db=db,
            family_id=current_user.family_id,
            title=schedule.title,
            description=schedule.description,
            start_time=schedule.start_time,
            end_time=schedule.end_time,
            priority=schedule.priority,
            repeat_type=schedule.repeat_type,
            repeat_until=schedule.repeat_until,
            is_reminder_enabled=schedule.is_reminder_enabled,
            reminder_minutes=schedule.reminder_minutes,
            participant_ids=schedule.participant_ids,
        )
        return db_schedule
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


@router.get("", response_model=ScheduleList, summary="获取日程列表")
async def get_schedules_endpoint(
    search: ScheduleSearch = Query(),
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """获取日程列表"""
    schedules, total = await get_schedules(
        db=db,
        family_id=current_user.family_id,
        skip=search.skip(),
        limit=search.limit(),
        start_date=search.start_date,
        end_date=search.end_date,
        status=search.status,
        priority=search.priority,
        search=search.keyword,
    )
    return ScheduleList(schedules=schedules, total=total)


@router.get("/upcoming", response_model=list[ScheduleResponse])
async def get_upcoming_schedules_endpoint(
    days_ahead: int = Query(7, ge=1, le=365, description="提前天数"),
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """获取即将到来的日程"""
    schedules = await get_upcoming_schedules(
        db=db, family_id=current_user.family_id, days_ahead=days_ahead
    )
    return schedules


@router.get("/by-date-range", response_model=list[ScheduleResponse])
async def get_schedules_by_date_range_endpoint(
    start_date: datetime = Query(..., description="开始日期"),
    end_date: datetime = Query(..., description="结束日期"),
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """根据日期范围获取日程"""
    if start_date >= end_date:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="开始日期必须早于结束日期"
        )

    schedules = await get_schedules_by_date_range(
        db=db,
        family_id=current_user.family_id,
        start_date=start_date,
        end_date=end_date,
    )
    return schedules


@router.get("/stats", response_model=ScheduleStats)
async def get_schedule_stats_endpoint(
    start_date: datetime | None = Query(None, description="开始日期"),
    end_date: datetime | None = Query(None, description="结束日期"),
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """获取日程统计信息"""
    stats = await get_schedule_stats(
        db=db,
        family_id=current_user.family_id,
        start_date=start_date,
        end_date=end_date,
    )
    return stats


@router.get("/{schedule_id}", response_model=ScheduleDetailResponse)
async def get_schedule_endpoint(
    schedule_id: int,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """获取日程详情"""
    schedule = await get_schedule_by_id(db, schedule_id, current_user.family_id)
    if not schedule:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="日程不存在")

    # 获取参与者
    participants = await get_schedule_participants(
        db, schedule_id, current_user.family_id
    )

    # 转换为响应模型
    schedule_response = ScheduleResponse.model_validate(schedule)
    participant_responses = [
        ScheduleParticipantResponse.model_validate(p) for p in participants
    ]

    return ScheduleDetailResponse(
        **schedule_response.model_dump(), participants=participant_responses
    )


@router.put("/{schedule_id}", response_model=ScheduleResponse)
async def update_schedule_endpoint(
    schedule_id: int,
    schedule_update: ScheduleUpdate,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """更新日程"""
    # 构建更新参数,只包含非None的字段
    update_data = {}
    for field, value in schedule_update.model_dump(exclude_unset=True).items():
        if field != "participant_ids":  # participant_ids 单独处理
            update_data[field] = value

    schedule = await update_schedule(
        db=db, schedule_id=schedule_id, family_id=current_user.family_id, **update_data
    )

    if not schedule:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="日程不存在")

    # 更新参与者
    if schedule_update.participant_ids is not None:
        # 删除现有参与者
        await db.execute(
            ScheduleParticipant.__table__.delete().where(
                ScheduleParticipant.schedule_id == schedule_id,
                ScheduleParticipant.family_id == current_user.family_id,
            )
        )
        # 添加新参与者
        if schedule_update.participant_ids:
            await add_schedule_participants(
                db, schedule_id, current_user.family_id, schedule_update.participant_ids
            )
        await db.commit()
        await db.refresh(schedule)

    return schedule


@router.delete("/{schedule_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_schedule_endpoint(
    schedule_id: int,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """删除日程"""
    success = await delete_schedule(db, schedule_id, current_user.family_id)
    if not success:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="日程不存在")


@router.get(
    "/{schedule_id}/participants", response_model=list[ScheduleParticipantResponse]
)
async def get_schedule_participants_endpoint(
    schedule_id: int,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """获取日程参与者列表"""
    # 验证日程存在
    schedule = await get_schedule_by_id(db, schedule_id, current_user.family_id)
    if not schedule:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="日程不存在")

    participants = await get_schedule_participants(
        db, schedule_id, current_user.family_id
    )
    return participants


@router.post(
    "/{schedule_id}/participants/{participant_id}/confirm",
    response_model=ScheduleParticipantResponse,
)
async def confirm_schedule_participation_endpoint(
    schedule_id: int,
    participant_id: int,
    current_user: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """确认日程参与"""
    # 验证日程存在
    schedule = await get_schedule_by_id(db, schedule_id, current_user.family_id)
    if not schedule:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="日程不存在")

    participant = await confirm_schedule_participation(
        db, participant_id, current_user.family_id
    )
    if not participant:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="参与者不存在"
        )

    return participant
